home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / xlib04.zip / XMAIN.ASM < prev    next >
Assembly Source File  |  1992-11-12  |  39KB  |  1,256 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XMAIN
  3. ;
  4. ; Initialization, panning and split screen functions for all MODE X 256
  5. ; Color resolutions
  6. ;
  7. ; Compile with Tasm.
  8. ; C callable.
  9. ;
  10. ;
  11. ; ****** XLIB - Mode X graphics library                ****************
  12. ; ******                                               ****************
  13. ; ****** Written By Themie Gouthas                     ****************
  14. ;
  15. ; egg@dstos3.dsto.gov.au
  16. ; teg@bart.dsto.gov.au
  17. ;
  18. ; MODIFICATIONS:
  19. ;  26-9-92:          Pel panning code added
  20. ;  Dates forgotten:  Numerous ;^)
  21. ;-----------------------------------------------------------------------
  22.  
  23.  
  24. include xlib.inc
  25. include xmain.inc
  26.  
  27.  
  28.     .data
  29.  
  30.  
  31. ; Mode X CRTC register tweaks for various resolutions
  32.  
  33.  
  34. X320Y200 label  word
  35.     db      0e3h    ; dot clock
  36.     db      02      ; Number of CRTC Registers to update
  37.     dw      00014h  ; turn off dword mode
  38.     dw      0e317h  ; turn on byte mode
  39.     dw      320     ; width
  40.     dw      200     ; height
  41.  
  42. X320Y240 label  word
  43.     db      0e3h    ; dot clock
  44.     db      10      ; Number of CRTC Registers to update
  45.     dw      00d06h  ; vertical total
  46.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  47.     dw      04109h  ; cell height (2 to double-scan)
  48.     dw      0ea10h  ; v sync start
  49.     dw      0ac11h  ; v sync end and protect cr0-cr7
  50.     dw      0df12h  ; vertical displayed
  51.     dw      00014h  ; turn off dword mode
  52.     dw      0e715h  ; v blank start
  53.     dw      00616h  ; v blank end
  54.     dw      0e317h  ; turn on byte mode
  55.     dw      320     ; width
  56.     dw      240     ; height
  57.  
  58. X360Y200 label  word
  59.     db      0e7h    ; dot clock
  60.     db      08      ; Number of CRTC Registers to update
  61.     dw      06b00h  ; horz total
  62.     dw      05901h  ; horz displayed
  63.     dw      05a02h  ; start horz blanking
  64.     dw      08e03h  ; end horz blanking
  65.     dw      05e04h  ; start h sync
  66.     dw      08a05h  ; end h sync
  67.     dw      00014h  ; turn off dword mode
  68.     dw      0e317h  ; turn on byte mode
  69.     dw      360     ; width
  70.     dw      200     ; height
  71.  
  72. X360Y240  label word
  73.     db      0e7h    ; dot clock
  74.     db      17      ; Number of CRTC Registers to update
  75.     dw    06b00h    ; horz total
  76.     dw    05901h    ; horz displayed
  77.     dw    05a02h    ; start horz blanking
  78.     dw    08e03h    ; end horz blanking
  79.     dw    05e04h    ; start h sync
  80.     dw    08a05h    ; end h sync
  81.     dw      00d06h  ; vertical total
  82.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  83.     dw      04109h  ; cell height (2 to double-scan)
  84.     dw      0ea10h  ; v sync start
  85.     dw      0ac11h  ; v sync end and protect cr0-cr7
  86.     dw      0df12h  ; vertical displayed
  87.     dw    02d13h    ; offset;
  88.     dw      00014h  ; turn off dword mode
  89.     dw      0e715h  ; v blank start
  90.     dw      00616h  ; v blank end
  91.     dw      0e317h  ; turn on byte mode
  92.     dw      360
  93.     dw      240
  94.  
  95. X376Y282 label word
  96.     db      0e7h
  97.     db      18
  98.     dw    06e00h    ; horz total
  99.     dw    05d01h    ; horz displayed
  100.     dw    05e02h    ; start horz blanking
  101.     dw    09103h    ; end horz blanking
  102.     dw    06204h    ; start h sync
  103.     dw    08f05h    ; end h sync
  104.     dw    06206h    ; vertical total
  105.     dw    0f007h    ; overflow
  106.     dw      06109h  ; cell height
  107.     dw      0310fh  ;
  108.     dw    03710h    ; v sync start
  109.     dw    08911h    ; v sync end and protect cr0-cr7
  110.     dw    03312h    ; vertical displayed
  111.     dw    02f13h    ; offset
  112.     dw    00014h    ; turn off dword mode
  113.     dw    03c15h    ; v blank start
  114.     dw    05c16h    ; v blank end
  115.     dw    0e317h    ; turn on byte mode
  116.     dw      376
  117.     dw      564
  118.  
  119.  
  120. X320Y400 label  word
  121.     db      0e3h    ; dot clock
  122.     db      03      ; Number of CRTC Registers to update
  123.     dw    04009h    ; cell height
  124.     dw      00014h  ; turn off dword mode
  125.     dw      0e317h  ; turn on byte mode
  126.     dw      320     ; width
  127.     dw      400     ; height
  128.  
  129. X320Y480 label  word
  130.     db      0e3h    ; dotclock
  131.     db      10      ; Number of CRTC Registers to update
  132.     dw      00d06h  ; vertical total
  133.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  134.     dw      04009h  ; cell height (2 to double-scan)
  135.     dw      0ea10h  ; v sync start
  136.     dw      0ac11h  ; v sync end and protect cr0-cr7
  137.     dw      0df12h  ; vertical displayed
  138.     dw      00014h  ; turn off dword mode
  139.     dw      0e715h  ; v blank start
  140.     dw      00616h  ; v blank end
  141.     dw      0e317h  ; turn on byte mode
  142.     dw      320     ; width
  143.     dw      480     ; height
  144.  
  145. X360Y400 label  word
  146.     db      0e7h    ; dot clock
  147.     db      09      ; Number of CRTC Registers to update
  148.     dw      06b00h  ; horz total
  149.     dw      05901h  ; horz displayed
  150.     dw      05a02h  ; start horz blanking
  151.     dw      08e03h  ; end horz blanking
  152.     dw      05e04h  ; start h sync
  153.     dw      08a05h  ; end h sync
  154.     dw    04009h    ; cell height
  155.     dw      00014h  ; turn off dword mode
  156.     dw      0e317h  ; turn on byte mode
  157.     dw      360     ; width
  158.     dw      400     ; height
  159.  
  160.  
  161.  
  162. X360Y480  label word
  163.     db      0e7h
  164.     db      17
  165.     dw    06b00h    ; horz total
  166.     dw    05901h    ; horz displayed
  167.     dw    05a02h    ; start horz blanking
  168.     dw    08e03h    ; end horz blanking
  169.     dw    05e04h    ; start h sync
  170.     dw    08a05h    ; end h sync
  171.     dw    00d06h    ; vertical total
  172.     dw    03e07h    ; overflow
  173.     dw    04009h    ; cell height
  174.     dw    0ea10h    ; v sync start
  175.     dw    0ac11h    ; v sync end and protect cr0-cr7
  176.     dw    0df12h    ; vertical displayed
  177.     dw    02d13h    ; offset
  178.     dw    00014h    ; turn off dword mode
  179.     dw    0e715h    ; v blank start
  180.     dw    00616h    ; v blank end
  181.     dw    0e317h    ; turn on byte mode
  182.     dw      360
  183.     dw      480
  184.  
  185. X360Y360  label word
  186.     db      0e7h
  187.     db      15
  188.     dw    06b00h    ; horz total
  189.     dw    05901h    ; horz displayed
  190.         dw    05a02h    ; start horz blanking
  191.     dw    08e03h    ; end horz blanking
  192.     dw    05e04h    ; start h sync
  193.     dw    08a05h    ; end h sync
  194.     dw    04009h    ; cell height
  195.     dw    08810h    ; v sync start
  196.     dw    08511h    ; v sync end and protect cr0-cr7
  197.     dw    06712h    ; vertical displayed
  198.     dw      02d13h  ; offset
  199.     dw    00014h    ; turn off dword mode
  200.     dw    06d15h    ; v blank start
  201.     dw    0ba16h    ; v blank end
  202.     dw    0e317h    ; turn on byte mode
  203.     dw      360
  204.     dw      360
  205.  
  206.  
  207. X376Y308 label word
  208.     db      0e7h
  209.     db      18
  210.     dw    06e00h    ; horz total
  211.     dw    05d01h    ; horz displayed
  212.     dw    05e02h    ; start horz blanking
  213.     dw    09103h    ; end horz blanking
  214.     dw    06204h    ; start h sync
  215.     dw    08f05h    ; end h sync
  216.     dw    06206h    ; vertical total
  217.     dw    00f07h    ; overflow
  218.     dw      04009h  ;
  219.     dw      0310fh  ;
  220.     dw    03710h    ; v sync start
  221.     dw    08911h    ; v sync end and protect cr0-cr7
  222.     dw    03312h    ; vertical displayed
  223.     dw    02f13h    ; offset
  224.     dw    00014h    ; turn off dword mode
  225.     dw    03c15h    ; v blank start
  226.     dw    05c16h    ; v blank end
  227.     dw    0e317h    ; turn on byte mode
  228.     dw      376
  229.     dw      308
  230.  
  231. X376Y564 label word
  232.     db      0e7h
  233.     db      18
  234.     dw    06e00h    ; horz total
  235.     dw    05d01h    ; horz displayed
  236.     dw    05e02h    ; start horz blanking
  237.     dw    09103h    ; end horz blanking
  238.     dw    06204h    ; start h sync
  239.     dw    08f05h    ; end h sync
  240.     dw    06206h    ; vertical total
  241.     dw    0f007h    ; overflow
  242.     dw      06009h  ;
  243.     dw      0310fh  ;
  244.     dw    03710h    ; v sync start
  245.     dw    08911h    ; v sync end and protect cr0-cr7
  246.     dw    03312h    ; vertical displayed
  247.     dw    02f13h    ; offset
  248.     dw    00014h    ; turn off dword mode
  249.     dw    03c15h    ; v blank start
  250.     dw    05c16h    ; v blank end
  251.     dw    0e317h    ; turn on byte mode
  252.     dw      376
  253.     dw      564
  254.  
  255. LAST_X_MODE         equ    11
  256. ModeTable label word    ; Mode X tweak table
  257.     dw      offset X320Y200
  258.     dw      offset X320Y240
  259.     dw      offset X360Y200
  260.     dw      offset X360Y240
  261.     dw      offset X376Y282
  262.     dw      offset X320Y400
  263.     dw      offset X320Y480
  264.     dw      offset X360Y400
  265.     dw      offset X360Y480
  266.     dw      offset X360Y360
  267.     dw      offset X376Y308
  268.     dw      offset X376Y564
  269.  
  270.  
  271. PARAMS label byte
  272.  
  273.     _CurrXMode               dw 0   ; Current graphics mode index
  274.     _InGraphics              db 0   ; Flag indicating graphics activity
  275.     _ScrnPhysicalByteWidth   dw 0   ; Physical width in bytes of screen
  276.     _ScrnPhysicalPixelWidth  dw 0   ; Physical width in pixels of screen
  277.     _ScrnPhysicalHeight      dw 0   ; Physical Height of screen
  278.     _ErrorValue              db 0   ; Set after function calls
  279.  
  280.  
  281.     _SplitScrnActive         db 0   ; Flag indicating Split scrn activity
  282.     _DoubleBufferActive      dw 0   ; Flag indicating double buffering
  283.  
  284.     _SplitScrnScanLine       dw 0   ; Split Screen's starting scan line
  285.     _SplitScrnVisibleHeight  dw 0   ; Split Screen's height on screen
  286.  
  287.     _SplitScrnOffs           dw 0   ; Offset in video ram of Split Screen
  288.                     ; always = 0
  289.     _Page0_Offs              dw 0   ; Ofset in video ram of Main virtual
  290.                     ; screen ( = 0 if no split screen
  291.                     ; otherwise = offset of first byte
  292.                     ; after split screen
  293.     _Page1_Offs              dw 0   ; Ofset in video ram of Second virtual
  294.                     ; screen ( = 0 if no split screen
  295.                     ; otherwise = offset of first byte
  296.                     ; after split screen
  297.                     ; = Page0_Offs if Doubble buffering
  298.                     ; not enabled
  299.     _NonVisual_Offs          dw 0   ; Ofset in video ram of first byte
  300.                     ; of non visible ram
  301.     _ScrnLogicalByteWidth    dw 0   ; Logical width in bytes of screen
  302.     _ScrnLogicalPixelWidth   dw 0   ; Logical width in pixels of screen
  303.     _ScrnLogicalHeight       dw 0   ; Logical Height of screen
  304.  
  305.     _MaxScrollX              dw 0   ; Max X start position of Physical
  306.                     ; screen within virtual screen (in
  307.                     ; bytes)
  308.     _MaxScrollY              dw 0   ; Max Y start position of Physical
  309.                     ; screen within virtual screen
  310.  
  311.     _VisiblePageIdx          dw 0   ; Index of currently visible D.B.
  312.                     ; page
  313.  
  314.     PageAddrTable label word
  315.     _VisiblePageOffs     dw 0   ; Table containing starting offsets
  316.     _HiddenPageOffs         dw 0   ; of the double buffer pages
  317.  
  318.         _TopClip                 dw 0   ; Clipping Rectangle
  319.         _BottomClip              dw 0   ;
  320.         _LeftClip                dw 0   ; Left/Right coordinates in bytes
  321.         _RightClip               dw 0   ;
  322.     _PhysicalStartByteX      dw 0   ; X byte coord of physical screen
  323.                     ; relative to virtual virtual screen
  324.     _PhysicalStartPixelX     dw 0   ; X pixel coord of physical screen
  325.                     ; relative to virtual screen
  326.     _PhysicalStartY          dw 0   ; Y pixel coord of physical screen
  327.                     ; relative to virtual screen
  328.  
  329. PARAMS_END label byte
  330.  
  331. PARAM_COUNT equ ($-PARAMS)
  332.  
  333.  
  334. ; Index/data pairs for CRT Controller registers that differ between
  335. ; mode 13h and mode X.
  336.  
  337.     ;Pelpan values for 0,1,2,3 pixel panning to the left, respectively
  338.     PelPanMask              db      000h,002h,004h,006h
  339.  
  340. DoubleScanFlag db ?     ; Flag to indicate double scanned mode
  341.  
  342.     .code
  343.  
  344. ;-------------------------------------------------------------------------
  345. ; Local Logical Screen Width setting function
  346. ; cx = Requitrd Logical Width
  347. ;
  348. ; WARNING: no registers are preserved
  349.  
  350. SetLogicalScrWidth proc
  351.     mov   dx,CRTC_INDEX
  352.     mov   al,CRTC_OFFSET
  353.     out   dx,al
  354.     inc   dx
  355.  
  356.     mov   ax,cx
  357.     cmp   ax,[_ScrnPhysicalPixelWidth]; Is logical width >= physical width
  358.     jge   @@ValidLogicalWidth          ; yes - continue
  359.     mov   ax,bx                        ; no - set logical width = physical
  360.  
  361. @@ValidLogicalWidth:
  362.     shr   ax,3
  363.     out   dx,al
  364.  
  365.     ; The EXACT logical pixel width may not have been possible since
  366.     ; it should be divisible by 8. Round down to the closest possible
  367.     ; width and update the status variables
  368.  
  369.     shl   ax,1
  370.     mov   bx,ax
  371.     mov   [_ScrnLogicalByteWidth],ax  ; Store the byte width of virtual
  372.         mov   [_RightClip],ax             ; Set default Right clip column
  373.                       ; screen
  374.     sub   ax,[_ScrnPhysicalByteWidth] ; Calculate and store Max X position
  375.     shl   ax,2                        ; of physical screen in virtual
  376.     mov   [_MaxScrollX],ax            ; screen in pixels
  377.     mov   ax,bx                       ; set ax to byte width of virt scrn
  378.     shl   ax,2                        ; convert to pixels
  379.     mov   [_ScrnLogicalPixelWidth],ax ; store virt scrn pixel width
  380.     mov   cx,ax                       ; save ax (return value)
  381.  
  382.     ; calculate no. non split screen rows in video ram
  383.  
  384.     mov   ax,0ffffh                ; cx = Maximum video ram offset
  385.     sub   dx,dx                    ; DX:AX is divide operand,  set DX = 0
  386.     div   bx                       ; divide ax by ScrnLogicalByteWidth
  387.     mov   [_ScrnLogicalHeight],ax  ; Save Screen Logical Height
  388.         mov   [_BottomClip],ax         ; Set default bottom clip row
  389.     sub   ax,[_ScrnPhysicalHeight] ; Update the maximum Y position of
  390.     mov   [_MaxScrollY],ax         ; Physical screen in logical screen
  391.     mov   ax,cx                    ; restore ax (return value)
  392.  
  393.     ; calculate initial NonVisual
  394.     mov  ax,[_ScrnLogicalByteWidth]
  395.     mul  [_ScrnPhysicalHeight]
  396.     mov  [_NonVisual_Offs],ax
  397.  
  398. @@Done: ret
  399. SetLogicalScrWidth endp
  400.  
  401.  
  402.  
  403.  
  404. ;-----------------------------------------------------------------------
  405. ; Mode X graphics mode set with a virtual screen
  406. ;   logical screen width.
  407. ; C near-callable as:
  408. ;
  409. ;    int x_set_mode(unsigned int mode,unsigned int WidthInPixels);
  410. ;
  411. ; returns the actual width of the allocated virtual screen in pixels
  412. ; if a valid mode was selected otherwise returns -1
  413. ;
  414. ; Saves virtual screen pixel width in _ScrnLogicalPixelWidth.
  415. ; Saves virtual screen byte  width in _ScrnLogicalByteWidth.
  416. ; Physical screen dimensions are set in _ScrnPhysicalPixelWidth,
  417. ; _ScrnPhysicalByteWidth and _ScrnPhysicalHeight
  418. ;
  419. ;
  420. ; Modes:  0  = 320 x 200  (256 color)  NOTE: Some of these modes require
  421. ;      1  = 320 x 240  (256 color)     vertical size adjustment.
  422. ;         2  = 360 x 200  (256 color)
  423. ;         3  = 360 x 240  (256 color)
  424. ;         4  = 320 x 400  (256 color)
  425. ;      5  = 320 x 480  (256 color)
  426. ;         6  = 360 x 200  (256 color)
  427. ;         7  = 360 x 480  (256 color)
  428. ;         8  = 360 x 360  (256 color)
  429. ;         9  = 376 x 308  (256 color)
  430. ;        10 = 376 x 564  (256 color)
  431. ;
  432. ; Written by Themie Gouthas,
  433. ; parts adapted from M. Abrash code.
  434. ;------------------------------------------------------------------------
  435. _x_set_mode proc
  436.     ARG   mode:word,logicalscrwidth:word
  437.     push  bp      ;preserve caller's stack frame
  438.     mov   bp,sp
  439.  
  440.     push  si      ;preserve C register vars
  441.     push  di      ; (don't count on BIOS preserving anything)
  442.  
  443.     cld
  444.     mov   ax,ds
  445.     mov   es,ax
  446.     mov   di,offset PARAMS
  447.     xor   ax,ax
  448.     mov   cx,PARAM_COUNT
  449.     rep   stosb
  450.  
  451.     mov   cx,[mode]
  452.     cmp   cx,LAST_X_MODE        ; have we selected a valid mode
  453.     jle   @@ValidMode           ; Yes !
  454.  
  455.     mov   [_InGraphics],FALSE   ; No return -1
  456.     mov   ax,-1
  457.     pop   di
  458.     pop   si
  459.     pop   bp
  460.     ret
  461.  
  462. @@ValidMode:
  463.  
  464.     mov   [_CurrXMode],cx
  465.     mov   [_InGraphics],TRUE
  466.  
  467.     xor   al,al
  468.     cmp   cx,3
  469.     jg    @@SetDoubleScanFlag
  470.     mov   al,TRUE
  471. @@SetDoubleScanFlag:
  472.     mov   [DoubleScanFlag],al
  473.  
  474.     mov   ax,13h                ; let the BIOS set standard 256-color
  475.     int   10h                   ;  mode (320x200 linear)
  476.  
  477.     mov   dx,SC_INDEX
  478.     mov   ax,0604h
  479.     out   dx,ax                 ; disable chain4 mode
  480.     mov   ax,0100h
  481.     out   dx,ax                ; synchronous reset while setting Misc
  482.                     ;  Output for safety, even though clock
  483.                     ;  unchanged
  484.  
  485.     mov   bx,offset ModeTable
  486.     shl   cx,1
  487.     add   bx,cx
  488.     mov   si, word ptr [bx]
  489.     lodsb
  490.  
  491.     mov   dx,MISC_OUTPUT
  492.     out   dx,al               ; select the dot clock and Horiz
  493.                   ;  scanning rate
  494.     mov   dx,SC_INDEX
  495.     mov   ax,0300h
  496.     out   dx,ax           ; undo reset (restart sequencer)
  497.  
  498.  
  499.     mov   dx,CRTC_INDEX       ; reprogram the CRT Controller
  500.     mov   al,11h              ; VSync End reg contains register write
  501.     out   dx,al               ; protect bit
  502.     inc   dx                  ; CRT Controller Data register
  503.     in    al,dx               ; get current VSync End register setting
  504.     and   al,07fh             ; remove write protect on various
  505.     out   dx,al               ; CRTC registers
  506.     dec   dx                  ; CRT Controller Index
  507.     cld
  508.     xor   cx,cx
  509.     lodsb
  510.     mov   cl,al
  511.  
  512. @@SetCRTParmsLoop:
  513.     lodsw                     ; get the next CRT Index/Data pair
  514.     out   dx,ax              ; set the next CRT Index/Data pair
  515.     loop  @@SetCRTParmsLoop
  516.  
  517.     mov   dx,SC_INDEX
  518.     mov   ax,0f02h
  519.     out   dx,ax          ; enable writes to all four planes
  520.     mov   ax,SCREEN_SEG       ; now clear all display memory, 8 pixels
  521.     mov   es,ax               ; at a time
  522.     sub   di,di               ; point ES:DI to display memory
  523.     sub   ax,ax               ; clear to zero-value pixels
  524.     mov   cx,8000h            ; # of words in display memory
  525.     rep   stosw               ; clear all of display memory
  526.  
  527.  
  528.     ;  Set pysical screen dimensions
  529.  
  530.     lodsw                               ; Load scrn pixel width
  531.     mov   [_ScrnPhysicalPixelWidth],ax  ;  from tweak table and store
  532.     mov   [_SplitScrnScanLine],ax       ; No splitscrn ==
  533.                         ; splitscrn=PhysicalscrnHeight
  534.     mov   bx,ax                         ; Copy width for later use
  535.     shr   ax,2                          ; Convert to byte width
  536.     mov   [_ScrnPhysicalByteWidth],ax   ; Store for later use
  537.     lodsw                               ; Load Screen Phys. Height
  538.     mov   [_ScrnPhysicalHeight],ax      ; Store for later use
  539.  
  540.  
  541.     ;  Mode X is set, now set the required logical page width.
  542.  
  543.     mov     cx,[logicalscrwidth]
  544.  
  545.     call    SetLogicalScrWidth
  546.  
  547.     pop     di      ;restore C register vars
  548.     pop     si
  549.     pop     bp      ;restore caller's stack frame
  550.     ret
  551. _x_set_mode endp
  552.  
  553. ;----------------------------------------------------------------------
  554. ; Mode X (256 color mode) set default access video plane
  555. ;
  556. ; C near-callable as:
  557. ;    void x_select_default_plane(unsigned char plane);
  558. ;
  559. ; Enables Read/Write access to a plane using general memory access
  560. ; methods
  561. ;
  562. ; Written by Themie Gouthas
  563. ;----------------------------------------------------------------------
  564. _x_select_default_plane proc
  565. ARG Plane:byte
  566.         push bp
  567.     mov  bp,sp       ; set up stack frame
  568.         mov  cl,byte ptr [Plane]
  569.  
  570.         ; SELECT WRITE PLANE
  571.     and  cl,011b              ;CL = plane
  572.     mov  ax,0100h + MAP_MASK  ;AL = index in SC of Map Mask reg
  573.     shl  ah,cl                ;set only the bit for the required
  574.                   ; plane to 1
  575.     mov  dx,SC_INDEX          ;set the Map Mask to enable only the
  576.     out  dx,ax                ; pixel's plane
  577.  
  578.         ; SELECT READ PLANE
  579.         mov  ah,cl                ;AH = plane
  580.     mov  al,READ_MAP          ;AL = index in GC of the Read Map reg
  581.     mov  dx,GC_INDEX          ;set the Read Map to read the pixel's
  582.     out  dx,ax              ; plane
  583.  
  584.         pop  bp
  585.         ret
  586. _x_select_default_plane endp
  587.  
  588.  
  589. ;----------------------------------------------------------------------
  590. ; Mode X (256 color mode) Set Mode X split screen starting row
  591. ; The split screen resides on the bottom half of the screen and has a
  592. ; starting address of A000:0000
  593. ;
  594. ; C near-callable as:
  595. ;    void x_set_splitscreen(unsigned int line);
  596. ;
  597. ; Updates _Page0_Offs to reflect the existence of the split screen region
  598. ; ie _MainScrnOffset is set to the offset of the first pixel beyond the split
  599. ; screen region
  600. ;
  601. ; Written by Themie Gouthas
  602. ;----------------------------------------------------------------------
  603.  
  604. _x_set_splitscreen proc
  605.     ARG Line:word
  606.     push bp
  607.     mov  bp,sp       ; set up stack frame
  608.     push si
  609.  
  610.     xor  si,si       ; si=0 -> x virtual page start coord
  611.  
  612.     cmp  [_DoubleBufferActive],0
  613.     jne   @@error
  614.  
  615.     cmp  [_SplitScrnActive],0
  616.     je   @@NotPreviouslyCalled
  617.  
  618. @@error:
  619.     mov  [_ErrorValue],ERROR
  620.     pop  si
  621.     pop  bp          ; Return if previously called
  622.     ret
  623.  
  624. @@NotPreviouslyCalled:
  625.  
  626.     ; Turn on split screen pal pen suppression, so the split screen
  627.     ; wo'nt be subject to pel panning as is the non split screen portion.
  628.  
  629.     mov  dx,INPUT_STATUS_0
  630.     in   al,dx                  ; Reset the AC Index/Data toggle to
  631.                     ;  index state
  632.     mov  al,AC_MODE_CONTROL+20h ; Bit 5 set to prevent screen blanking
  633.     mov  dx,AC_INDEX        ; Point AC to Index/Data register
  634.     out  dx,al
  635.     inc  dx                     ; Point to AC Data reg (for reads only)
  636.     in   al,dx                  ; Get the current AC Mode Control reg
  637.     or   al,20h                 ; Enable split scrn Pel panning suppress.
  638.     dec  dx                     ; Point to AC Index/Data reg (for writes only)
  639.     out  dx,al                  ; Write the new AC Mode Control setting
  640.                     ;  with split screen pel panning
  641.                     ;  suppression turned on
  642.  
  643.     mov  [_PhysicalStartByteX],ax   ; Set the Phisical screen start
  644.     mov  [_PhysicalStartPixelX],ax  ; offset within virtual screen
  645.     mov  [_PhysicalStartY],ax
  646.     mov  [_SplitScrnActive],TRUE
  647.     mov  ax,[Line]
  648.     jns  @@NotNeg    ; Check that Split Scrn start scan line is +ve
  649.  
  650.     mov  ax,0        ; Since -ve set to 0
  651.  
  652. @@NotNeg:
  653.     mov  [_SplitScrnScanLine],ax   ; save the scanline
  654.  
  655.  
  656.  
  657.     mov  cl,[DoubleScanFlag]
  658.     shl  ax,cl            ; Mode X 200 and 240 line modes are actually
  659.                   ; 400 and 480 lines that are double scanned
  660.                   ; so for start scanline multiply required ModeX
  661.                   ; scan line by 2 if its a double scanned mode
  662.  
  663.     mov  bx,ax             ; save the scanline
  664.  
  665.  
  666.     WaitVsyncStart        ; wait for vertical retrace
  667.  
  668.     cli                   ; Dont allow register setting to be interrupted
  669.     mov  dx,CRTC_INDEX
  670.     mov  ah,bl
  671.     mov  al,LINE_COMPARE
  672.     out  dx,ax          ; Bits 7-0 of the split screen scan line
  673.  
  674.     mov  ah,bh
  675.     and  ah,1
  676.     shl  ah,4
  677.     mov  al,OVERFLOW     ; Bit 4 of overflow register = Bit 8 of split
  678.     out  dx,al           ; screen scan line,
  679.     inc  dx              ; So using readability of VGA registers
  680.     in   al,dx           ; Read the OVERFLOW register, and set the
  681.     and  al, not 10h     ; bit corresponding to Bit 8 (above)
  682.     or   al,ah
  683.     out  dx,al
  684.  
  685.     dec  dx
  686.     mov  ah,bh
  687.     and  ah,2
  688.     ror  ah,3
  689.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  690.     out  dx,al             ; Bit 9 of split screen scan line
  691.     inc  dx                ; As we did before, update the apropriate
  692.     in   al,dx             ; bit without disturbing the rest
  693.     and  al, not 40h
  694.     or   al,ah
  695.     out  dx,al
  696.     sti                    ; Registers are set, so interrupts are safe
  697.  
  698.     mov  ax,[_ScrnPhysicalHeight]     ; Determine where the first byte
  699.     sub  ax,[_SplitScrnScanLine]      ; of the non split screen video ram
  700.     mov  [_SplitScrnVisibleHeight],bx ; starts and store it for reference
  701.  
  702.     mov  bx,[_ScrnLogicalByteWidth]
  703.     mul  bx
  704.     mov  [_Page0_Offs],ax
  705.     mov  [_Page1_Offs],ax
  706.  
  707.     ; calculate no. non split screen rows in video ram
  708.     mov  cx,0ffffh             ; cx = Maximum video ram offset
  709.     sub  cx,ax                 ; cx = cx - _Page0_Offs
  710.     xchg cx,ax                 ; swap cx and ax
  711.     sub  dx,dx                 ; DX:AX is divide operand,  set DX = 0
  712.     div  bx                    ; divide ax (prev cx) by
  713.                    ; ScrnLogicalByteWidth
  714.  
  715.     mov  [_ScrnLogicalHeight],ax     ; Save Screen Logical Height
  716.         cmp   ax,[_BottomClip]
  717.         jle   @@BottomClipOK             ; Adjust Clip Rectangle if necessary
  718.         mov   [_BottomClip],ax
  719. @@BottomClipOK:
  720.     sub  ax,[_SplitScrnScanLine]     ; Update the maximum Y position of
  721.     mov  [_MaxScrollY],ax             ; Physical screen in logical screen
  722.  
  723.     xchg cx,ax                    ; restore original ax (MainScrnOfs)
  724.     mov  bh,al                    ; Set the visible screen start address
  725.     mov  ch,ah                    ; to the top left corner of the virtual
  726.     jmp  short StartAddrEntry     ; screen
  727. _x_set_splitscreen     endp
  728.  
  729.  
  730. ;-----------------------------------------------------------------------
  731. ; Mode X (256 color mode) Page flip primer
  732. ; No clipping is performed.
  733. ; C near-callable as:
  734. ;
  735. ;    void x_page_flip(unsigned int x, unsigned int y);
  736. ;
  737. ; Swaps visible and hidden page offsets and then executes the SetStartAddr
  738. ; to achieve a page flip.
  739. ;
  740. ; SEE x_set_start_addr below
  741. ;
  742. ; Written by Themie Gouthas
  743. ;------------------------------------------------------------------------
  744.  
  745. _x_page_flip proc
  746.     ARG x:word,y:word
  747.     push  bp                  ;preserve caller's stack frame
  748.     mov   bp,sp               ;point to local stack frame
  749.     push  si
  750.  
  751.     mov  si,[x]
  752.     mov  ax,[_ScrnLogicalByteWidth]     ; Calculate Offset increment
  753.     mov  cx,[y]
  754.     mul  cx                             ; for Y
  755.     cmp  [_DoubleBufferActive],TRUE     ; Do we have double buffering ?
  756.     jne  PageFlipEntry1
  757.  
  758.     mov  bx,[_HiddenPageOffs]
  759.     xchg bx,[_VisiblePageOffs]          ; Swap the Page Offsete
  760.     xchg [_HiddenPageOffs],bx
  761.     xor  [_VisiblePageIdx],01h          ; Set the Visible page index
  762.     jmp  short PageFlipEntry2
  763. _x_page_flip endp
  764.  
  765.  
  766. ;-----------------------------------------------------------------------
  767. ; Mode X (256 color mode) Set Mode X non split screen start address
  768. ;   of logical screen.
  769. ; C near-callable as:
  770. ;
  771. ;    void x_set_start_addr(unsigned int x, unsigned int y);
  772. ;
  773. ; Params: StartOffset is offset of first byte of logical screen ram
  774. ;           (Useful if you want to double buffer by splitting your non
  775. ;            split screen video ram into 2 pages)
  776. ;        X,Y coordinates of the top left hand corner of the physical screen
  777. ;           within the logical screen
  778. ;           X must not exceed (Logical screen width - Physical screen width)
  779. ;           Y must not exceed (Logical screen height - Physical screen height)
  780. ;
  781. ;
  782. ; Written by Themie Gouthas,
  783. ; Parts addapted from M. Abrash code published in DDJ Mag.
  784. ;------------------------------------------------------------------------
  785. _x_set_start_addr proc
  786.     ARG x:word,y:word
  787.     push bp
  788.     mov  bp,sp
  789.     push si
  790.  
  791.     mov  si,[x]
  792.     mov  ax,[_ScrnLogicalByteWidth]     ; Calculate Offset increment
  793.     mov  cx,[y]                         ; for Y
  794.     mul  cx
  795.     cmp  [_DoubleBufferActive],TRUE     ; Do we have double buffering ?
  796.     je   @@PageResolution
  797. PageFlipEntry1:
  798.     add  ax,[_Page0_Offs]               ; no - add page 0 offset
  799.     jmp  short @@AddColumn
  800.  
  801. PageFlipEntry2:
  802.  
  803.     mov  [_PhysicalStartPixelX],si
  804.     mov  [_PhysicalStartY],cx
  805.  
  806. @@PageResolution:
  807.     add  ax,[_VisiblePageOffs]          ; Add visible page offset
  808.  
  809. @@AddColumn:
  810.     mov  cx,si
  811.     shr  cx,2
  812.         mov  [_PhysicalStartByteX],cx
  813.     add  ax,cx                          ; add the column offset for X
  814.     mov  bh,al                          ; setup CRTC start addr regs and
  815.                         ; values in word registers for
  816.     mov  ch,ah                          ; fast word outs
  817.  
  818. StartAddrEntry:
  819.     mov  bl,ADDR_LOW
  820.     mov  cl,ADDR_HIGH
  821.  
  822.  
  823.     mov  dx,INPUT_STATUS_0    ;Wait for trailing edge of Vsync pulse
  824.  
  825. @@WaitDE:
  826.     in   al,dx
  827.     test al,01h
  828.     jnz  @@WaitDE             ;display enable is active low (0 = active)
  829.  
  830.     mov  dx,CRTC_INDEX
  831.     mov  ax,bx
  832.     out  dx,ax               ;start address low
  833.     mov  ax,cx
  834.     out  dx,ax               ;start address high
  835.  
  836.         mov  dx,AC_INDEX
  837.     mov  al,PEL_PANNING+20h   ; Point the attribute controller to pel pan
  838.     out  dx,al                ; reg. Bit 5 also set to prevent blanking
  839.  
  840.     and  si,0003h             ; select pel pan register value for the
  841.     mov  al,PelPanMask[si]    ; required x coordinate
  842.     out  dx,al                ; load new Pel Pan setting.
  843.  
  844. ; Now wait for vertical sync, so the other page will be invisible when
  845. ; we start drawing to it.
  846.  
  847.         WaitVsyncStart
  848.  
  849.     mov  [_ErrorValue],OK
  850.     pop  si
  851.     pop  bp
  852.     ret
  853. _x_set_start_addr  endp
  854.  
  855.  
  856. ;-----------------------------------------------------------------------
  857. ; Mode X (256 color mode) Mode X split screen hide
  858. ; C near-callable as:
  859. ;
  860. ;    void x_hide_splitscreen()
  861. ;
  862. ; Hides an existing split screen by setting its starting scan line to
  863. ; the last physical screen scan line
  864. ;
  865. ; WARNING: Only to be used if SplitScrnLine has been previously called
  866. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  867. ;       the initial split screen is reserved and the size limitations
  868. ;       of these modes means any change in the split screen scan line
  869. ;          will encroach on the split screen ram
  870. ;
  871. ; Written by Themie Gouthas
  872. ;------------------------------------------------------------------------
  873.  
  874. _x_hide_splitscreen proc
  875.     push bp
  876.     mov  bp,sp
  877.  
  878.     cmp  [_SplitScrnActive],TRUE
  879.     je   @@SplitScreenEnabled
  880.  
  881. @@error:
  882.         mov  [_ErrorValue],ERROR
  883.     pop  bp
  884.     ret
  885.  
  886. @@SplitScreenEnabled:
  887.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  888.     jg   @@error
  889.     mov  bx,[_ScrnPhysicalHeight]
  890.  
  891.         mov  ax,[_ScrnLogicalHeight]
  892.     sub  ax,bx
  893.     mov  [_MaxScrollY],ax
  894.     xor  ax,ax
  895.     mov  [_SplitScrnVisibleHeight],ax
  896.  
  897.     mov  cl,[DoubleScanFlag]  ; Compensate for double scanned modes
  898.     shl  bx,cl
  899.  
  900.     WaitVsyncStart               ; wait for vertical retrace
  901.  
  902.     cli                 ; Dont allow register setting to be interrupted
  903.     mov  dx,CRTC_INDEX
  904.     mov  ah,bl
  905.     mov  al,LINE_COMPARE
  906.     out  dx,ax          ; Bits 7-0 of the split screen scan line
  907.  
  908.     mov  ah,bh
  909.     and  ah,1
  910.     shl  ah,4
  911.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  912.     out  dx,al        ; screen scan line,
  913.     inc  dx           ; So using readability of VGA registers
  914.     in   al,dx        ; Read the OVERFLOW register, and set the
  915.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  916.     or   al,ah
  917.     out  dx,al
  918.  
  919.     dec  dx
  920.     mov  ah,bh
  921.     and  ah,2
  922.     ror  ah,3
  923.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  924.     out  dx,al             ; Bit 9 of split screen scan line
  925.     inc  dx                ; As we did before, update the apropriate
  926.     in   al,dx             ; bit without disturbing the rest
  927.     and  al, not 40h
  928.     or   al,ah
  929.     out  dx,al
  930.     sti                  ; Registers are set, so interrupts are safe
  931.  
  932. @@done:
  933.  
  934.         mov  [_ErrorValue],OK
  935.     pop  bp
  936.     ret
  937. _x_hide_splitscreen endp
  938.  
  939. ;-----------------------------------------------------------------------
  940. ; Mode X (256 color mode) Mode X split screen show
  941. ; C near-callable as:
  942. ;
  943. ;    void x_show_splitscreen()
  944. ;
  945. ; Restores split screen start scan line to the initial split screen
  946. ; starting scan line as set by SplitScrnLine.
  947. ;
  948. ; WARNING: Only to be used if SplitScrnLine has been previously called
  949. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  950. ;       the initial split screen is reserved and the size limitations
  951. ;       of these modes means any change in the split screen scan line
  952. ;          will encroach on the split screen ram
  953. ;          Update: Now disabled for these modes
  954. ;
  955. ; Written by Themie Gouthas
  956. ;------------------------------------------------------------------------
  957.  
  958.  
  959. _x_show_splitscreen proc
  960.     push bp
  961.     mov  bp,sp
  962.  
  963.     cmp  [_SplitScrnActive],TRUE
  964.     je   @@SplitScreenEnabled
  965.  
  966. @@error:
  967.         mov  [_ErrorValue],ERROR
  968.     pop  bp
  969.     ret
  970.  
  971. @@SplitScreenEnabled:
  972.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  973.     jg   @@error
  974.  
  975.     mov  bx,[_SplitScrnScanLine]
  976.     mov  ax,[_ScrnLogicalHeight] ; Update Max Scroll Y
  977.     sub  ax,bx
  978.         mov  [_MaxScrollY],ax
  979.  
  980.     mov  ax,[_ScrnPhysicalHeight]
  981.     sub  ax,bx
  982.     mov  [_SplitScrnVisibleHeight],ax
  983.  
  984.     mov  cl,[DoubleScanFlag]  ; Compensate for double scanned modes
  985.     shl  bx,cl
  986.     WaitVsyncStart               ; wait for vertical retrace
  987.  
  988.     cli                 ; Dont allow register setting to be interrupted
  989.     mov  dx,CRTC_INDEX
  990.     mov  ah,bl
  991.     mov  al,LINE_COMPARE
  992.     out  dx,ax                ; Bits 7-0 of the split screen scan line
  993.  
  994.     mov  ah,bh
  995.     and  ah,1
  996.     shl  ah,4
  997.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  998.     out  dx,al        ; screen scan line,
  999.     inc  dx           ; So using readability of VGA registers
  1000.     in   al,dx        ; Read the OVERFLOW register, and set the
  1001.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  1002.     or   al,ah
  1003.     out  dx,al
  1004.  
  1005.     dec  dx
  1006.     mov  ah,bh
  1007.     and  ah,2
  1008.     ror  ah,3
  1009.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  1010.     out  dx,al             ; Bit 9 of split screen scan line
  1011.     inc  dx                ; As we did before, update the apropriate
  1012.     in   al,dx             ; bit without disturbing the rest
  1013.     and  al, not 40h
  1014.     or   al,ah
  1015.     out  dx,al
  1016.     sti                  ; Registers are set, so interrupts are safe
  1017.  
  1018. @@Done:
  1019.         mov  [_ErrorValue],0
  1020.     pop  bp
  1021.     ret
  1022. _x_show_splitscreen endp
  1023.  
  1024.  
  1025. ;-----------------------------------------------------------------------
  1026. ; Mode X (256 color mode) Modify Mode X split screen starting scan line
  1027. ; C near-callable as:
  1028. ;
  1029. ;    void x_adjust_splitscreen(unsigned int ScanLine)
  1030. ;
  1031. ; Sets the split screen start scan line to a new scan line. Valid scan lines
  1032. ; are between the initial split screen starting scan line and the last
  1033. ; physical screen scan line.
  1034. ;
  1035. ; WARNING: Only to be used if SplitScrnLine has been previously called
  1036. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  1037. ;       the initial split screen is reserved and the size limitations
  1038. ;       of these modes means any change in the split screen scan line
  1039. ;          will encroach on the split screen ram
  1040. ;          Update: Now disabled for these modes
  1041. ;
  1042. ;
  1043. ; Written by Themie Gouthas
  1044. ;------------------------------------------------------------------------
  1045.  
  1046.  
  1047. _x_adjust_splitscreen proc
  1048.     ARG   ScanLine
  1049.     push bp
  1050.     mov  bp,sp
  1051.  
  1052.     cmp  [_SplitScrnActive],TRUE
  1053.     je   @@SplitScreenEnabled
  1054.  
  1055. @@error:
  1056.         mov  [_ErrorValue],ERROR
  1057.     pop  bp
  1058.     ret
  1059.  
  1060. @@SplitScreenEnabled:
  1061.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  1062.     jg   @@error
  1063.     mov  bx,[ScanLine]            ; Is the required starting scan line
  1064.     cmp  bx,[_SplitScrnScanLine]  ; valid ?
  1065.     js   @@Done                   ; No - Then do nothing
  1066.  
  1067. @@ValidScanLine:
  1068.  
  1069.         mov  ax,[_ScrnLogicalHeight] ; Update Max Scroll Y
  1070.     sub  ax,bx
  1071.         mov  [_MaxScrollY],ax
  1072.  
  1073.     mov  ax,[_ScrnPhysicalHeight]
  1074.     sub  ax,bx
  1075.     mov  [_SplitScrnVisibleHeight],ax
  1076.  
  1077.  
  1078.     mov  cl,[DoubleScanFlag]   ; Compensate for double scanned modes
  1079.     shl  bx,cl
  1080.  
  1081.     WaitVsyncStart      ; wait for vertical retrace
  1082.  
  1083.     cli                 ; Dont allow register setting to be interrupted
  1084.  
  1085.     mov  dx,CRTC_INDEX
  1086.     mov  ah,bl
  1087.     mov  al,LINE_COMPARE
  1088.     out  dx,ax          ; Bits 7-0 of the split screen scan line
  1089.  
  1090.     mov  ah,bh
  1091.     and  ah,1
  1092.     shl  ah,4
  1093.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  1094.     out  dx,al        ; screen scan line,
  1095.     inc  dx           ; So using readability of VGA registers
  1096.     in   al,dx        ; Read the OVERFLOW register, and set the
  1097.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  1098.     or   al,ah
  1099.     out  dx,al
  1100.  
  1101.     dec  dx
  1102.     mov  ah,bh
  1103.     and  ah,2
  1104.     ror  ah,3
  1105.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  1106.     out  dx,al             ; Bit 9 of split screen scan line
  1107.     inc  dx                ; As we did before, update the apropriate
  1108.     in   al,dx             ; bit without disturbing the rest
  1109.     and  al, not 40h
  1110.     or   al,ah
  1111.     out  dx,al
  1112.     sti                    ; Registers are set, so interrupts are safe
  1113. @@Done:
  1114.         mov  [_ErrorValue],OK
  1115.     pop   bp
  1116.     ret
  1117. _x_adjust_splitscreen endp
  1118.  
  1119.  
  1120.  
  1121. ;-----------------------------------------------------------------------
  1122. ; Mode X (256 color mode) Enable DoubleBuffering on non split screen area
  1123. ; C near-callable as:
  1124. ;
  1125. ;    int x_set_doublebuffer(unsigned int PageHeight);
  1126. ;
  1127. ; Params: PageHeight is the height of the virtual screen to double buffer
  1128. ;         Returns the closest possible height to the specified.
  1129. ;
  1130. ; Sets up two double buffering virtual pages
  1131. ; GLOBAL variables set:
  1132. ;
  1133. ;      _Page1_Offs        Offset of second virtual page
  1134. ;      _NonVisual_Offs          Offset of first non visible video ram byte
  1135. ;      _DoubleBufferActive      Flag
  1136. ;      _PageAddrTable           Table of Double buffering pages start offsets
  1137. ;      _ScrnLogicalHeight       Logical height of the double buffering pages
  1138. ;
  1139. ;
  1140. ; Written by Themie Gouthas
  1141. ;------------------------------------------------------------------------
  1142.  
  1143.  
  1144. _x_set_doublebuffer proc
  1145.        ARG PageHeight:word
  1146.        push  bp
  1147.        mov   bp,sp
  1148.  
  1149.        cmp   [_DoubleBufferActive],0
  1150.        je    @@OkToContinue
  1151. @error:
  1152.        mov   [_ErrorValue],ERROR
  1153.        pop   bp
  1154.        ret
  1155.  
  1156. @@OkToContinue:
  1157.        mov   [_VisiblePageIdx],0     ; Set visible Page to 0
  1158.        mov   ax,[_ScrnLogicalHeight] ; Set Maximum D.B. Page height to
  1159.        shr   ax,1                    ;   _ScrnLogicalHeight / 2
  1160.  
  1161.        mov   bx,[PageHeight]         ; Is the require D.B. Page Height
  1162.        cmp   ax,bx                   ;  > the Maximum  D.B. Page Height ?
  1163.  
  1164.        js    @@InvalidHeight         ; no  - jump
  1165.        mov   ax,bx                   ; yes - Set the D.B. Page height to
  1166.                      ;       to the maximum allowed.
  1167.  
  1168. @@InvalidHeight:
  1169.        mov   [_ScrnLogicalHeight],ax    ; Update logical screen height to
  1170.                     ;  reflect the height of a D.B. page
  1171.        cmp   ax,[_BottomClip]
  1172.        jle   @@BottomClipOK             ; Adjust Clip Rectangle if necessary
  1173.        mov   [_BottomClip],ax
  1174. @@BottomClipOK:
  1175.        mov   dx,ax
  1176.        mul   [_ScrnLogicalByteWidth]    ; Calculate the offset of the second
  1177.        mov   cx,ax                    ;  D.B. Page in video ram
  1178.        mov   bx,[_Page0_Offs]
  1179.        mov   [_VisiblePageOffs],bx
  1180.  
  1181.        add   ax,bx
  1182.        mov   [_Page1_Offs],ax           ; Save it
  1183.        mov   [_HiddenPageOffs],ax
  1184.  
  1185.        add   ax,cx                      ; Calculate the offset of first byte
  1186.        mov   [_NonVisual_Offs],ax       ;  beyond the D.B. pages and save it
  1187.        mov   [_DoubleBufferActive],TRUE ; Set flag indicating D.B'ing mode on
  1188.  
  1189.        mov   ax,dx
  1190.        sub   ax,[_ScrnPhysicalHeight]
  1191.        add   ax,[_SplitScrnVisibleHeight]
  1192.        mov   [_MaxScrollY],ax
  1193.  
  1194.        mov   ax,dx                      ; return the D.B. pages' height
  1195.        mov   [_ErrorValue],OK
  1196.        pop   bp
  1197.        ret
  1198. _x_set_doublebuffer endp
  1199.  
  1200.  
  1201. ;-----------------------------------------------------------------------
  1202. ; Set Clipping rectangle
  1203. ; C callable as:
  1204. ;
  1205. ;
  1206. ;    int x_set_cliprect(WORD left,WORD top, WORD right, WORD bottom);
  1207. ;
  1208. ;
  1209. ; NOTE clipping is byte oriented. "left" and "right" are in bytes not pixels.
  1210. ;    Only selected functions perform any clipping at all.
  1211. ;
  1212. ; Written by Themie Gouthas
  1213. ;------------------------------------------------------------------------
  1214.  
  1215. _x_set_cliprect proc
  1216. ARG left:word,top:word,right:word,bottom:word
  1217.        push  bp
  1218.        mov   bp,sp
  1219.        mov   ax,[left]
  1220.        mov   bx,[right]
  1221.        cmp   bx,ax
  1222.        jns   @@CorrectXOrder
  1223.        xchg  bx,ax
  1224. @@CorrectXOrder:
  1225.        mov   [_LeftClip],ax
  1226.        mov   [_RightClip],bx
  1227.        mov   ax,[top]
  1228.        mov   bx,[bottom]
  1229.        cmp   bx,ax
  1230.        jns   @@CorrectYOrder
  1231.        xchg  bx,ax
  1232. @@CorrectYOrder:
  1233.        mov   [_TopClip],ax
  1234.        mov   [_BottomClip],bx
  1235.        pop   bp
  1236.        ret
  1237. _x_set_cliprect endp
  1238.  
  1239.  
  1240. ;----------------------------------------------------------------------
  1241. ; Return to text mode
  1242. ;
  1243. _x_text_mode proc
  1244.        push  bp
  1245.  
  1246.        mov   ax,03h        ; Restore Text Mode
  1247.        int   10h
  1248.  
  1249.        pop   bp
  1250.        ret
  1251. _x_text_mode endp
  1252.  
  1253.  
  1254.     end
  1255.  
  1256.